package com.ruoyi.system.service.impl;

import java.awt.geom.QuadCurve2D;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import cn.hutool.core.date.DateUtil;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.vo.PointsRankVo;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.PointsManagementMapper;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

/**
 * 积分管理Service业务层处理
 *
 * @author ruoyi
 * @date 2024-04-22
 */
@Service
public class PointsManagementServiceImpl implements IPointsManagementService
{
    @Autowired
    private PointsManagementMapper pointsManagementMapper;
    @Autowired
    private IMeetingUserSignatureService meetingUserSignatureService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IActivityUserSignatureService activityUserSignatureService;
    @Autowired
    private IPointsRuleService pointsRuleService;
    @Autowired
    private IWorkSummaryService workSummaryService;

    /**
     * 查询积分管理
     *
     * @param id 积分管理主键
     * @return 积分管理
     */
    @Override
    public PointsManagement selectPointsManagementById(Long id)
    {
        PointsManagement management = pointsManagementMapper.selectPointsManagementById(id);
        String fileUrl = management.getFileUrl();
        if(StringUtils.isNotBlank(fileUrl)){
            List<String> fileUrlList = Arrays.asList(fileUrl.split(","));
            management.setFileUrlList(fileUrlList);
        }
        return management;
    }

    /**
     * 查询积分管理列表
     *
     * @param pointsManagement 积分管理
     * @return 积分管理
     */
    @Override
    public List<PointsManagement> selectPointsManagementList(PointsManagement pointsManagement)
    {
        List<PointsManagement> pointsManagements = pointsManagementMapper.selectPointsManagementList(pointsManagement);
        for(PointsManagement management : pointsManagements){
            String fileUrl = management.getFileUrl();
            if(StringUtils.isNotBlank(fileUrl)){
                List<String> fileUrlList = Arrays.asList(fileUrl.split(","));
                management.setFileUrlList(fileUrlList);
            }
        }
        return pointsManagements;
    }

    /**
     * 新增积分管理
     *
     * @param pointsManagement 积分管理
     * @return 结果
     */
    @Override
    public int insertPointsManagement(PointsManagement pointsManagement)
    {
        pointsManagement.setCreateTime(DateUtils.getNowDate());
        List<String> fileUrlList = pointsManagement.getFileUrlList();
        if(!CollectionUtils.isEmpty(fileUrlList)){
            String fileUrl = StringUtils.join(fileUrlList, ",");
            pointsManagement.setFileUrl(fileUrl);
        }
        return pointsManagementMapper.insertPointsManagement(pointsManagement);
    }

    /**
     * 修改积分管理
     *
     * @param pointsManagement 积分管理
     * @return 结果
     */
    @Override
    public int updatePointsManagement(PointsManagement pointsManagement)
    {
        pointsManagement.setUpdateTime(DateUtils.getNowDate());
        List<String> fileUrlList = pointsManagement.getFileUrlList();
        String fileUrl = StringUtils.join(fileUrlList, ",");
        pointsManagement.setFileUrl(fileUrl);
        return pointsManagementMapper.updatePointsManagement(pointsManagement);
    }

    /**
     * 删除积分管理信息
     *
     * @param id 积分管理主键
     * @return 结果
     */
    @Override
    public int deletePointsManagementById(Long id)
    {
        return pointsManagementMapper.deletePointsManagementById(id);
    }

    /**
     * 修改状态
     *
     * @param pointsManagement 积分管理
     * @return 结果
     */
    @Override
    public int updatePointsManagementStatus(PointsManagement pointsManagement){
        PointsManagement management = new PointsManagement();
        management.setId(pointsManagement.getId());
        management.setStatus(pointsManagement.getStatus());
        return pointsManagementMapper.updatePointsManagement(pointsManagement);
    }


    /**
     * 添加系统规则积分
     *
     * @param pointsRuleSystems 系统规则
     * @return 结果
     */
    @Override
    public void insertPointsManagementSystem( List<PointsRuleSystem> pointsRuleSystems,String startTime,String endTime){
        for(PointsRuleSystem rule : pointsRuleSystems){
            String ruleType = rule.getRuleType();
            if("0".equals(ruleType)){
                insertPointsManagementByMeetingType(rule,startTime,endTime);
            }else if("1".equals(ruleType)){
                //累计会议时长
                insertPointsManagementByMeetingTime(rule,startTime,endTime);
            }else if("2".equals(ruleType)){
                //参加活动类型
                insertPointsManagementByActivityType(rule,startTime,endTime);
            }else if("3".equals(ruleType)){
                //累计活动时长
                insertPointsManagementByActivityTime(rule,startTime,endTime);
            }else if("4".equals(ruleType)){
                //提交总结类型
                insertPointsManagementByWorkSummaryType(rule,startTime,endTime);
            }
        }
    }


    /**
     * 按照年度查询个人积分统计
     */
    @Override
    public TableDataInfo selectRank(PointsManagement pointsManagement){
        List<PointsRankVo> resultList = new ArrayList();
        Long pointsRuleId = pointsManagement.getPointsRuleId();
        SysUser user = new SysUser();
        List<SysUser> sysUsers = sysUserService.selectUserList(user);
        //计算人员积分
          //查询规则初始分
        PointsRule pointsRule = pointsRuleService.selectPointsRuleById(pointsRuleId);
        String initialScore = pointsRule.getInitialScore();
        Float initial= Float.valueOf(initialScore);
        PointsManagement management = new PointsManagement();
        management.setPointsRuleId(pointsRuleId);
        for(SysUser sysuser : sysUsers){
            PointsRankVo pointsRankVo = new PointsRankVo();
            pointsRankVo.setUserId(sysuser.getUserId());
            pointsRankVo.setUserName(sysuser.getUserName());
            pointsRankVo.setDeptId(sysuser.getDeptId());
            pointsRankVo.setDeptName(sysuser.getDept().getDeptName());
            pointsRankVo.setPointsRuleId(pointsRuleId);
            pointsRankVo.setPointsRuleName(pointsRule.getPointsRuleName());
            pointsRankVo.setPostName(sysuser.getPostName());
            //查询人员人工规则得分情况
            Long userId = sysuser.getUserId();
            management.setUserId(userId);
            management.setStatus("1");
            management.setRuleCategory("0");
            management.setStartTime(pointsManagement.getStartTime());
            management.setEndTime(pointsManagement.getEndTime());
            List<PointsManagement> pointsManagementArtificial = pointsManagementMapper.selectPointsManagementList(management);
            //系统规则
            management.setStatus("");
            management.setRuleCategory("1");
            management.setStartTime(pointsManagement.getStartTime());
            management.setEndTime(pointsManagement.getEndTime());
            List<PointsManagement> pointsManagementSystem = pointsManagementMapper.selectPointsManagementList(management);
            pointsManagementArtificial.addAll(pointsManagementSystem);
            Float totalAddScore = 0f;
            Float totalSubtractScore = 0f;
            for(PointsManagement point : pointsManagementArtificial){
                String executeScore = point.getExecuteScore();
                String modified = point.getModified();
                if("0".equals(modified)){
                    //加分
                    totalAddScore = totalAddScore + Float.valueOf(executeScore);
                }else if("1".equals(modified)){
                   //扣分
                    totalSubtractScore = totalSubtractScore + Float.valueOf(executeScore);
                }
            }
            pointsRankVo.setTotalAddScore(totalAddScore);
            pointsRankVo.setTotalSubtractScore(totalSubtractScore);
            float total = initial + totalAddScore - totalSubtractScore;
            pointsRankVo.setTotalScore(total);
            resultList.add(pointsRankVo);
        }
        resultList = resultList.stream()
                .sorted(Comparator.comparing(PointsRankVo::getTotalScore).reversed())
                .collect(Collectors.toList());
        int index = 0;
        double lastAge = -1;
        // 并列排名后名次不间断
        for (PointsRankVo vo : resultList) {
            if (Double.compare(lastAge, vo.getTotalScore()) != 0) {
                lastAge = vo.getTotalScore();
                index++;
            }
            vo.setOrderNum(index);
        }
        if(!ObjectUtils.isEmpty(pointsManagement.getUserId())){
            resultList = resultList.stream().filter(o -> o.getUserId().equals(pointsManagement.getUserId())).collect(Collectors.toList());
        }else if(!ObjectUtils.isEmpty(pointsManagement.getDeptId())){
            resultList = resultList.stream().filter(o -> o.getDeptId().equals(pointsManagement.getDeptId())).collect(Collectors.toList());
        }
        Integer num = resultList.size();
        Integer pageNum = pointsManagement.getPageNum();
        Integer pageSize = pointsManagement.getPageSize();
        List<PointsRankVo> list = resultList.stream().skip((pageNum - 1) * pageSize).limit(pageSize).collect(Collectors.toList());
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows(list);
        rspData.setTotal(num);
        return rspData;
    }

    public void insertPointsManagementByMeetingType(PointsRuleSystem rule,String startTime,String endTime){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getPointsScore();
        //查询人员参会次数
        SysUser user1 = new SysUser();
        List<SysUser> sysUserList = sysUserMapper.selectUserList(user1);
        for(SysUser user : sysUserList){
            Long userId = user.getUserId();
            //查询人员时间范围内签到次数  排除请假
            MeetingUserSignature userSignature = new MeetingUserSignature();
            userSignature.setUserId(userId);
            userSignature.setMeetingType(firstCondition);
            userSignature.setMeetingStartTime(startTime);
            userSignature.setMeetingEndTime(endTime);
            //根据会议类型查询人员签到次数
            List<MeetingUserSignature> meetingUserSignatures = meetingUserSignatureService.selectUserSignatureCountByMeetingType(userSignature);
            int count = meetingUserSignatures.size();
            PointsManagement management = new PointsManagement();
            management.setPointsRuleId(rule.getPointsRuleId());
            management.setPointsRuleSystemId(rule.getId());
            management.setPointsType(rule.getPointsType());
            management.setPointsProject(rule.getPointsProject());
            management.setPointsStandard(rule.getPointsStandard());
            management.setRuleCategory("1");
            management.setDeptId(user.getDeptId());
            management.setDeptName(user.getDeptName());
            management.setUserId(userId);
            management.setUserName(user.getUserName());
            management.setExecuteScore(pointsScore);
            if("0".equals(conditionJudge)){
                //大于
                if(count>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(count<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }
        }
    }

    public void insertPointsManagementByMeetingTime(PointsRuleSystem rule,String startTime,String endTime){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getPointsScore();
        //查询人员参会次数
        SysUser user1 = new SysUser();
        List<SysUser> sysUserList = sysUserMapper.selectUserList(user1);
        for(SysUser user : sysUserList){
            Long userId = user.getUserId();
            //查询人员时间范围内签到次数  排除请假
            MeetingUserSignature userSignature = new MeetingUserSignature();
            userSignature.setUserId(userId);
            userSignature.setMeetingType(firstCondition);
            userSignature.setMeetingStartTime(startTime);
            userSignature.setMeetingEndTime(endTime);
            //根据会议类型查询人员参会时长
            Long differenceTime = 0L;
            List<MeetingUserSignature> meetingUserSignatures = meetingUserSignatureService.selectUserSignatureCountByMeetingType(userSignature);
            for(MeetingUserSignature meeting : meetingUserSignatures){
                String meetingStartTime = meeting.getMeetingStartTime();
                String meetingEndTime = meeting.getMeetingEndTime();
                Date meetingStart = DateUtil.parse(meetingStartTime);
                Date meetingEnd = DateUtil.parse(meetingEndTime);
                long difference = meetingEnd.getTime() - meetingStart.getTime();
                differenceTime = differenceTime+difference;
            }
            //处理会议时长
            PointsManagement management = new PointsManagement();
            management.setPointsRuleId(rule.getPointsRuleId());
            management.setPointsRuleSystemId(rule.getId());
            management.setPointsType(rule.getPointsType());
            management.setPointsProject(rule.getPointsProject());
            management.setPointsStandard(rule.getPointsStandard());
            management.setRuleCategory("1");
            management.setDeptId(user.getDeptId());
            management.setDeptName(user.getDeptName());
            management.setUserId(userId);
            management.setUserName(user.getUserName());
            management.setExecuteScore(pointsScore);
            long hour = differenceTime / (60 * 60 * 1000);
            if("0".equals(conditionJudge)){
                //大于
                if(hour>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(hour<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }
        }
    }

    public void insertPointsManagementByActivityType(PointsRuleSystem rule,String startTime,String endTime){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getPointsScore();
        //查询人员参加活动次数
        SysUser user1 = new SysUser();
        List<SysUser> sysUserList = sysUserMapper.selectUserList(user1);
        for(SysUser user : sysUserList){
            Long userId = user.getUserId();
            //查询人员时间范围内签到次数  排除请假
            ActivityUserSignature userSignature = new ActivityUserSignature();
            userSignature.setUserId(userId);
            userSignature.setActivityType(firstCondition);
            userSignature.setActivityStartTime(startTime);
            userSignature.setActivityEndTime(endTime);
            //根据活动类型查询人员签到次数
            List<ActivityUserSignature> activityUserSignatures = activityUserSignatureService.selectUserSignatureCountByActivityType(userSignature);
            int count = activityUserSignatures.size();
            PointsManagement management = new PointsManagement();
            management.setPointsRuleId(rule.getPointsRuleId());
            management.setPointsRuleSystemId(rule.getId());
            management.setPointsType(rule.getPointsType());
            management.setPointsProject(rule.getPointsProject());
            management.setPointsStandard(rule.getPointsStandard());
            management.setRuleCategory("1");
            management.setDeptId(user.getDeptId());
            management.setDeptName(user.getDeptName());
            management.setUserId(userId);
            management.setUserName(user.getUserName());
            management.setExecuteScore(pointsScore);
            if("0".equals(conditionJudge)){
                //大于
                if(count>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(count<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }
        }
    }

    public void insertPointsManagementByActivityTime(PointsRuleSystem rule,String startTime,String endTime){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getPointsScore();
        //查询人员参会次数
        SysUser user1 = new SysUser();
        List<SysUser> sysUserList = sysUserMapper.selectUserList(user1);
        for(SysUser user : sysUserList){
            Long userId = user.getUserId();
            //查询人员时间范围内签到次数  排除请假
            ActivityUserSignature userSignature = new ActivityUserSignature();
            userSignature.setUserId(userId);
            userSignature.setActivityType(firstCondition);
            userSignature.setActivityStartTime(startTime);
            userSignature.setActivityEndTime(endTime);
            Long differenceTime = 0L;
            //根据活动类型查询人员参会时长
            List<ActivityUserSignature> activityUserSignatures = activityUserSignatureService.selectUserSignatureCountByActivityType(userSignature);
            for(ActivityUserSignature activity : activityUserSignatures){
                String activityStartTime = activity.getActivityStartTime();
                String activityEndTime = activity.getActivityEndTime();
                Date activityStart = DateUtil.parse(activityStartTime);
                Date activityEnd = DateUtil.parse(activityEndTime);
                long difference = activityEnd.getTime() - activityStart.getTime();
                differenceTime = differenceTime+difference;
            }
            //处理会议时长
            PointsManagement management = new PointsManagement();
            management.setPointsRuleId(rule.getPointsRuleId());
            management.setPointsRuleSystemId(rule.getId());
            management.setPointsType(rule.getPointsType());
            management.setPointsProject(rule.getPointsProject());
            management.setPointsStandard(rule.getPointsStandard());
            management.setRuleCategory("1");
            management.setDeptId(user.getDeptId());
            management.setDeptName(user.getDeptName());
            management.setUserId(userId);
            management.setUserName(user.getUserName());
            management.setExecuteScore(pointsScore);
            long hour = differenceTime / (60 * 60 * 1000);
            if("0".equals(conditionJudge)){
                //大于
                if(hour>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(hour<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }
        }
    }

    public void insertPointsManagementByWorkSummaryType(PointsRuleSystem rule,String startTime,String endTime){
        String firstCondition = rule.getFirstCondition();
        String conditionJudge = rule.getConditionJudge();
        String secondCondition = rule.getSecondCondition();
        String modified = rule.getModified();
        String pointsScore = rule.getPointsScore();
        //查询人员工作总结次数
        SysUser user1 = new SysUser();
        List<SysUser> sysUserList = sysUserMapper.selectUserList(user1);
        for(SysUser user : sysUserList){
            Long userId = user.getUserId();
            //查询人员时间范围内工作总结次数
            WorkSummary workSummary = new WorkSummary();
            workSummary.setUserId(userId);
            workSummary.setSummaryType(firstCondition);
            workSummary.setStartTime(startTime);
            workSummary.setEndTime(endTime);
            //根据工作总结类型查询
            List<WorkSummary> workSummaries = workSummaryService.selectWorkSummaryList(workSummary);
            int count = workSummaries.size();
            PointsManagement management = new PointsManagement();
            management.setPointsRuleId(rule.getPointsRuleId());
            management.setPointsRuleSystemId(rule.getId());
            management.setPointsType(rule.getPointsType());
            management.setPointsProject(rule.getPointsProject());
            management.setPointsStandard(rule.getPointsStandard());
            management.setRuleCategory("1");
            management.setDeptId(user.getDeptId());
            management.setDeptName(user.getDeptName());
            management.setUserId(userId);
            management.setUserName(user.getUserName());
            management.setExecuteScore(pointsScore);
            if("0".equals(conditionJudge)){
                //大于
                if(count>Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }else if("1".equals(conditionJudge)){
                //小于
                if(count<Integer.valueOf(secondCondition)){
                    if("0".equals(modified)){
                        //加分
                        management.setModified("0");
                        insertPointsManagement(management);
                    }else{
                        //扣分
                        management.setModified("1");
                        insertPointsManagement(management);
                    }
                }
            }
        }
    }

}
